#include "main.h"
#include <sum_usbfs.h>

// USBFS配置
void setup_usbfs(void) {
	usbfs_gusbcs_expl_s gusbcs = {
		.force_dev_en = 1,
		.force_host_en = 0,
		.srp_en = 0,
		.hnp_en = 1,
		.timeout_cal = 0,
		.turnaround_time_clocks = 2,
	};
	usbfs_control(gusbcs);

	sleep_ms(20);

	usbfs_gccfg_expl_s gccfg = {
		.pwr_on = 1,
		.sof_out_en = 0,
		.vbus_a_cmp_en = 0,
		.vbus_b_cmp_en = 1,
		.vbus_ignore = 1,
	};
	usbfs_set_global_core_cfg(gccfg);

	usbfs_set_global_recv_fifo_32b_nums(128);

	usbfs_dieptflen_expl_s diep0tflen = {
		.addr_32b_no = 128,
		.size_32b_nums = 32,
	};
	usbfs_dieptflen_expl_s diep1tflen = {
		.addr_32b_no = 160,
		.size_32b_nums = 32,
	};
	usbfs_dieptflen_expl_s diep2tflen = {
		.addr_32b_no = 192,
		.size_32b_nums = 128,
	};
	usbfs_set_in_fifo_len(USBFS_DIEP0TFLEN, diep0tflen);
	usbfs_set_in_fifo_len(USBFS_DIEP1TFLEN, diep1tflen);
	usbfs_set_in_fifo_len(USBFS_DIEP2TFLEN, diep2tflen);

	usbfs_gint_expl_s ginten = {
		.cur_mode = USBFS_MODE_DEV,
		.mode_fault = 1,
		.otg = 0,
		.sof = 0,
		.recv_fifo_non_empty = 1,
		.non_periodic_trans_avl = 0,
		.global_non_periodic_in_nak = 0,
		.global_out_nak = 0,
		.early_suspend = 0,
		.suspend = 0,
		.reset = 1,
		.enum_finish = 1,
		.iso_out_drop = 0,
		.periodic_frame_end = 0,
		.in_ep = 1,
		.out_ep = 1,
		.iso_in_not_complete = 0,
		.iso_out_periodic_not_complete = 0,
		.host_port = 0,
		.host_channel = 0,
		.periodic_trans_fifo_low = 0,
		.id_pin_stat_change = 0,
		.disconnect = 0,
		.session = 0,
		.wakeup = 0,
	};
	usbfs_set_int_en(ginten);

	usbfs_gahbcs_expl_s gahbcs = {
		.global_int_en = 1,
		.trans_fifo_low_th = USBFS_GAHBCS_EMPTY_TH_HALF,
		.periodic_trans_fifo_low_th = USBFS_GAHBCS_EMPTY_TH_HALF,
	};
	usbfs_set_global_ahb_ctl(gahbcs);

	usbfs_dcfg_expl_s dcfg = {
		.speed = USBFS_DS_FULL_SPEED,
		.non_zero_len_pkt_stall_en = 0,
		.dev_addr = 0,
		.periodic_frame_end_time = USBFS_EOPFT_80_PERCENT,
	};
	usbfs_set_dev_cfg_s(dcfg);

	usbfs_diepint_expl_s diepinten = {
		.trans_finish = 1,
		.ep_disable = 1,
		.ctrl_in_timeout = 1,
		.trans_fifo_underrun = 1,
		.in_nak = 1,
		.trans_fifo_low = 1,
	};
	usbfs_set_dev_in_int_en(diepinten);

	usbfs_doepint_expl_s doepinten = {
		.trans_finish = 1,
		.ep_disable = 1,
		.setup_phase_finish = 1,
		.recv_fifo_overrun = 1,
		.back_to_back_setup = 1,
	};
	usbfs_set_dev_out_int_en(doepinten);

	usbfs_daepint_expl_s daepint = {
		.in_ep0_int = 1,
		.out_ep0_int = 1,
	};
	usbfs_set_dev_ep_int_en(daepint);
}
